#include "my_lib/rgb.h"

// #define RESET_WORD 64  //reset信号对应时长所占字节数
// #define RGB_NUM  8     //rgb灯数量
// #define CODE_0 0xC0    //0码
// #define CODE_1 0xFC    //1码

//rgb数据缓存
static uint8_t rgb_buffer[RGB_NUM*24+RESET_WORD] = {0};

static void RGB_SPI_Init(void)
{
    //外设时钟使能
    RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOB | RCC_AHB_PERIPH_DMA | RCC_AHB_PERIPH_GPIOB, ENABLE);
    RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2, ENABLE);

    //引脚配置
    GPIO_InitTypeDef GPIO_InitStructure;
    PB13_AFx_SPI2SCK();
    PB14_AFx_SPI2MISO();
    PB15_AFx_SPI2MOSI();
    //推挽输出
    GPIO_InitStructure.Pins = GPIO_PIN_15;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

    //spi配置
    SPI_InitTypeDef SPI_InitStructure;
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_TxOnly;    // 双线全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                         // 主机模式
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     // 帧数据长度为8bit
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            // 时钟空闲电平为低
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                          // 第一个边沿采样
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                             // 片选信号由SSI寄存器控制
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    // 波特率为PCLK的8分频
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    // 最高有效位 MSB 收发在前
    SPI_InitStructure.SPI_Speed = SPI_Speed_High;                          // 低速SPI
    SPI_Init(CW_SPI2, &SPI_InitStructure);
    SPI_Cmd(CW_SPI2, ENABLE);
}

/// @brief 位寻址rgb控制
/// @param addr rgb单位地址,0-(RGB_NUM-1)
/// @param RGB  rgb码 
static void SetRGB_One(uint8_t addr, uint32_t RGB)
{
    if(addr >= RGB_NUM){      //检测地址是否超出实际定义范围
        MY_LOGW("rgb", "addr is invalid");
        return;
    }
    for(uint8_t i=0; i<8; i++)   //设置G值
    {
        rgb_buffer[addr*24+i] = (RGB<<i)&0x008000? CODE_1:CODE_0;
    }
    for(uint8_t i=0; i<8; i++)  //设置R值
    {
        rgb_buffer[addr*24+8+i] = (RGB<<i)&0x800000? CODE_1:CODE_0;
    }
    for(uint8_t i=0; i<8; i++)  //设置B值
    {
        rgb_buffer[addr*24+16+i] = (RGB<<i)&0x000080? CODE_1:CODE_0;
    }
}

/// @brief rgb显存清零(不立即刷新)
/// @param  
static void RGB_CleanBuffer(void)
{
    for(uint8_t i=0; i<RGB_NUM; i++)
    {
        SetRGB_One(i, 0x000000);
    }
}

/// @brief 更新rgb数据缓存到设备
/// @param  
static void RGB_Refresh(void)
{
    uint16_t count = 0;
    while(count < sizeof(rgb_buffer)/sizeof(rgb_buffer[0]))
    {
        while(SPI_GetFlagStatus(CW_SPI2, SPI_FLAG_TXE) == RESET);
        SPI_SendData(CW_SPI2, rgb_buffer[count++]);
    }
}

/// @brief 初始化重置rgb
/// @param  
void RGB_Init(void)
{
    RGB_SPI_Init();
    RGB_CleanBuffer();
    RGB_Refresh();
}


///////////////////////temp test/////////////////////////////////////
uint32_t color_test = 0x000022;

void SetRGBTestColor(uint8_t red, uint8_t green, uint8_t blue)
{
    color_test = 0;
    color_test |= red<<16;
    color_test |= green<<8;
    color_test |= blue;
}

/// @brief rgb跑马灯测试
/// @param RGB_1 
/// @param RGB_2 
void RGB_Test(void)
{
    for(uint8_t i=0; i<RGB_NUM/2; i++)
    {
        SetRGB_One(i, color_test);
        SetRGB_One(RGB_NUM-1-i, color_test);
        RGB_Refresh();
    }

}
///////////////////////temp test/////////////////////////////////////

// void RGB_TaskHandler(uint16_t cycle)
// {
//     static uint32_t timeTick = 0;
//     if((GetTick()-timeTick) > cycle)
//     {
//         timeTick = GetTick();
//         RGB_Test();
//     }
// }

